home *** CD-ROM | disk | FTP | other *** search
- //*****************************************************************************
- // C_Task.prg
- // Task class for OBJECT v2.03
- // Copyright (c) 1991, JHK, JHK-Software, Piestany
- // Compile with: /N/M/W/A
- //-----------------------------------------------------------------------------
-
- #include "InKey.ch"
- #include "Object.ch"
-
- static TList:={} //task list
- static LastTask:={} //last active task
- static Cmd:=0 //command for execute with SetKey (InKey code)
-
- create class Task from Window //Usage sequence: Init, Process,... Done
- export: //YOU OVERWRITE: (Init()),VPaint(),VProcess(),(Done())
- var IsDead // false //true for dead task, need for correctly return from child(s) VProcess()
- var DoneBlock // {||true} //use for various setting in doneing any object.
- method New=TaskNew //o:New()
- method Init=TaskInit //o:Init(Name,R,C,Rs,Cs,Clr,Shadow)
- method GoodInit=TaskGoodInit //o:GoodInit(Name,R,C,Rs,Cs,CurSize,Clr,Shadow)
- method Top=TaskTop //o:Top(lRepaint) //make this task as last active task
- method VProcess=TaskVProcess //o:VProcess() //virtual process, use (overwrite) in child classes for execute application.
- method Process=TaskProcess //o:Process() //execute Init() and Done().
- method Done=TaskDone //o:Done(lRePaint) //true for RePaint windows (tasks)
- endclass
-
-
- //*****************************************************************************
- // Task:New() --> self
- // initialize new object
- //
- constructor TaskNew()
- ::IsDead:= false
- ::DoneBlock:= {||true}
- return(self)
-
-
- //-----------------------------------------------------------------------------
- // GetTList() --> TList
- // return task list
- //
- function GetTList()
- return(TList)
-
-
- //-----------------------------------------------------------------------------
- // SetLastTask([NewTask]) --> Task object
- // get/set last active task
- //
- function SetLastTask(NewTask) //nil value allowed!
- local lt:=LastTask
- if PCount()==1; LastTask:=NewTask; endif
- return(lt)
-
-
- //-----------------------------------------------------------------------------
- // RestartTask() --> true/false
- // return last active task from TList, need for menu class
- //
- function RestartTask()
- if Empty(TList); return(false); endif
- if !Empty(LastTask); return(LastTask:Process()); endif
- return(ATail(GetWList()):Process())
-
-
- //*****************************************************************************
- // Task:Init(Name,R,C,Rs,Cs,Clr,Shadow) --> true
- // initialize the task.
- //
- method function TaskInit(Name,R,C,Rs,Cs,Clr,Shadow)
- ::super(Window):Init(Name,R,C,Rs,Cs,Clr,Shadow)
- return(EndInit(self))
-
-
- //*****************************************************************************
- // Task:GoodInit(Name,R,C,Rs,Cs,CurSize,Clr,Shadow) --> true
- // initialize the task.
- //
- method function TaskGoodInit(Name,R,C,Rs,Cs,CurSize,Clr,Shadow)
- ::super(Window):GoodInit(Name,R,C,Rs,Cs,CurSize,Clr,Shadow)
- return(EndInit(self))
-
-
- //*****************************************************************************
- // Task::EndInit() --> true
- // initialize Task extension instvars
- //
- static function EndInit(Task)
- if !Task:UpFlag //for keeping children do not SetKeys...
- if Task:ID<=9
- SetKey(K_ALT_1+Task:ID-1,{||(Cmd:=LastKey()),StuffKey(nSwapTask)})
- endif
- if Empty(TList)
- SetKey(K_ALT_0, {||(Cmd:=K_ALT_0), StuffKey(nSwapTask)}) //task-list
- SetKey(K_F5, {||(Cmd:=K_F5), StuffKey(nSwapTask)}) //zoom-in
- SetKey(K_SH_F5, {||(Cmd:=K_SH_F5), StuffKey(nSwapTask)}) //zoom-out
- SetKey(K_F6, {||(Cmd:=K_F6), StuffKey(nSwapTask)}) //switch-forward
- SetKey(K_SH_F6, {||(Cmd:=K_SH_F6), StuffKey(nSwapTask)}) //switch-backward
- SetKey(K_F7, {||(Cmd:=K_F7), StuffKey(nSwapTask)}) //tile
- SetKey(K_SH_F7, {||(Cmd:=K_SH_F7), StuffKey(nSwapTask)}) //cascade
- SetKey(K_F8, {||(Cmd:=K_F8), StuffKey(nSwapTask)}) //drag
- SetKey(K_SH_F10,{||(Cmd:=K_SH_F10),StuffKey(nSwapTask)}) //local-window-menu
- endif
- AAdd(TList,Task)
- endif
- return(true)
-
-
- //*****************************************************************************
- // Task:Top(lRepaint) --> nil
- // make this task as last active task.
- //
- method function TaskTop(lRepaint)
- LastTask:=self
- return(::super(Window):Top(lRepaint))
-
-
- //*****************************************************************************
- // Task:VProcess() --> Task
- // virtual process, I recomend that You overwrite this method, for execute app.code.
- //
- method function TaskVProcess()
- PauseKey(0)
- return(self)
-
-
- //*****************************************************************************
- // Task:Process() --> true
- // this is main application loop.
- //
- method function TaskProcess()
- local nt, ct //NewTask, CurrentTask
- ct:=self
- if ct:UpFlag
- LastTask:=ct
- if !(ValType(nt:=ct:VProcess())$"LU"); ct:=nt; endif //change task allowed! //nt can be OBJECT or TRUE or NIL
- ct:SaveIn()
- else
- if Empty(LastTask)
- ct:Top(true) //RePaint!
- elseif ct:ID<>LastTask:ID
- ct:Top(false) //Paint!
- endif
- repeat
- if ct:IsMin
- SaveDOut(ResTxt(145))
- SaveHelpIdx({1})
- PauseKey(0)
- RestHelpIdx()
- RestDOut()
- else
- LastTask:=ct
- if !(ValType(nt:=ct:VProcess())$"LU"); ct:=nt; endif //change task allowed! //nt can be OBJECT or TRUE or NIL
- ct:SaveIn()
- endif
- if LastKey()==K_CTRL_RET; SetLastKey(K_ESC); endif //done==exit
- if LastKey()==K_ESC; Cmd:=K_ESC; endif //task::done()
- do case
- case K_ALT_1<=Cmd and Cmd<=K_ALT_9; ct:=Top(ct) //task-top (see ID)
- case Cmd==K_ALT_0; ct:=List(ct) //task-list
- case Cmd==K_ESC; ct:=Done(ct) //task-done virtual!
- case Cmd==K_F5; ZoomIn(ct) //zoom-out
- case Cmd==K_SH_F5; ZoomOut(ct) //zoom-out
- case Cmd==K_F6; ct:=Switch(ct,true) //switch-forward
- case Cmd==K_SH_F6; ct:=Switch(ct,false) //switch-backward
- case Cmd==K_F7; Tile(ct) //tile
- case Cmd==K_SH_F7; Cascade(ct) //cascade
- case Cmd==K_F8; ct:Drag() //move-size
- case Cmd==K_SH_F10; ct:=Menu(ct) //local-window-menu
- endcase
- Cmd:=0 //clear task command
- until LastKey()==nSwapTask
- endif
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Task::Top() --> newTask
- // make this task as active.
- //
- static function Top(Task)
- local i:=Cmd-K_ALT_1+1
- i:=AScan(TList,{|e|e:ID==i})
- if i>0
- Task:=TList[i]
- if Empty(LastTask) or Task:ID<>LastTask:ID; Task:Top(false); endif //paint!
- endif
- set lastkey K_ENTER
- return(Task)
-
-
- //-----------------------------------------------------------------------------
- // Task::List() --> newTask
- // list-menu of all active tasks.
- //
- static function List(Task)
- local Mnu
- local Choice
- local Items:={}
- local uLen
- AEval(TList,{|e|AAdd(Items,"(~"+NTrim(e:ID)+") "+e:Name)})
- uLen:=Max(AWidth(Items)+1,Len(ResTxt(022))+6)
- IEval(Min(Len(Items),9),{|i|Items[i]:=PadR(Items[i],uLen)+"Alt-"+NTrim(TList[i]:ID)})
- object Mnu of Mnu; Mnu:Init(ResTxt(022),-3,-3,,Items)
- SaveDOut(ResTxt(140))
- Choice:=Mnu:Process()
- RestDOut()
- Mnu:Done()
- if Choice>0
- Task:=TList[Choice]
- if Empty(LastTask) or Task:ID<>LastTask:ID; Task:Top(false); endif //paint!
- endif
- set lastkey K_ENTER
- return(Task)
-
-
- //-----------------------------------------------------------------------------
- // Task::Done() --> nil
- // static method: done task, if is possible.
- //
- static function Done(Task)
- local i:=AScan(TList,{|e|e:ID==Task:ID})
- local lExit:=Task:Done() //do not automatic repaint windows!
- set lastkey K_ENTER //assume: not exit
- if lExit
- set lastkey nSwapTask //force exit from this task
- if i>Len(TList); i--; endif
- if Empty(TList)
- LastTask:={} //clear LastTask info!
- else
- set lastkey K_ENTER //not exit
- Task:=ATail(GetWList())
- Task:Top(true) //repaint window!
- endif
- endif
- return(Task)
-
-
- //-----------------------------------------------------------------------------
- // Task::ZoomIn() --> true
- // zoom-minimize active task window.
- //
- static function ZoomIn(Task)
- if Task:IsMin
- Task:Restore()
- else
- Task:Minimize()
- endif
- set lastkey K_ENTER
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Task::ZoomOut() --> true
- // zoom-maximize active task window.
- //
- static function ZoomOut(Task)
- if Task:IsMax
- Task:Restore()
- else
- Task:Maximize()
- endif
- set lastkey K_ENTER
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Task::Switch(lForward) --> true
- // switch to next task.
- //
- static function Switch(Task,lForward)
- local TLen:=Len(TList)
- local i:=AScan(TList,{|e|e:ID==Task:ID})+if(lForward, +1, -1)
- if i<1; i:=TLen; endif
- if i>TLen; i:=1; endif
- if i<=TLen
- Task:=TList[i]
- if Empty(LastTask) or Task:ID<>LastTask:ID; Task:Top(false); endif //Paint!
- endif
- set lastkey K_ENTER
- return(Task)
-
-
- //-----------------------------------------------------------------------------
- // Task::Cascade() --> nil
- // cascade repaint all tasks.
- //
- static function Cascade(Task)
- local i
- local R:=1
- local C:=0
- local Rs:=MaxRow()-Len(TList)-3
- local Cs:=MaxCol()-Len(TList)
- AEval(TList,{|e|if(e:IsMin,(Rs++,Cs++),nil)})
- AEval(TList,{|e|if(!e:IsMin,(SetCoords(e,R,C,Rs,Cs),R++,C++),nil)})
- Task:RePaint(true)
- set lastkey K_ENTER
- return(true)
-
- static function SetCoords(Task,R,C,Rs,Cs)
- Task:Row:=R
- Task:Col:=C
- Task:WRow:=R
- Task:WCol:=C
- Task:RowSize:=Max(Min(Rs,Task:MaxRows),Task:MinRows)
- Task:ColSize:=Max(Min(Cs,Task:MaxCols),Task:MinCols)
- if Task:Row+Task:RowSize+1>=MaxRow(); Task:Row:=MaxRow()-Task:RowSize-2; endif
- if Task:Col+Task:ColSize>=MaxCol(); Task:Col:=MaxCol()-Task:ColSize-1; endif
- Task:WRowSize:=Task:RowSize
- Task:WColSize:=Task:ColSize
- Task:IsMax:=false
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Task::Tile() --> true
- // tile repaint all tasks.
- //
- static function Tile(Task)
- local R,C,Rs,Cs
- local i,j:=0,Ntw:=0
- AEval(TList,{|e|if(!e:IsMin,Ntw++,nil)}) //Ntw=NumberTiledWindows
- if Ntw==0; return(true); endif
- R:=1
- C:=0
- do case
- case Ntw==1; Rs:=MaxRow()-4; Cs:=MaxCol()-1 //1
- case Ntw==2; Rs:=Int((MaxRow()-6)/2); Cs:=MaxCol()-1 //2
- case Ntw==3; Rs:=Int((MaxRow()-6)/2); Cs:=Int((MaxCol()-1)/2)-1 //3
- case Ntw==4; Rs:=Int((MaxRow()-6)/2); Cs:=Int((MaxCol()-1)/2)-1 //4
- case Ntw<=6; Rs:=Int((MaxRow()-6)/2); Cs:=Int((MaxCol()-1)/3)-2 //5,6
- otherwise; Rs:=Int((MaxRow()-8)/3); Cs:=Int((MaxCol()-1)/3)-2 //7..9, next window will be minimized.
- endcase
- if Len(TList)==1
- TList[1]:Maximize()
- else
- for i:=1 to Len(TList)
- if ! TList[i]:IsMin
- j++ //next worked window
- if 1<j and j<10
- do case
- case Ntw==2
- R+=Rs+2; Rs+=if(MaxRow()>=39,1,0)
- case Ntw==3
- do case
- case j==2; C+=Cs+2
- case j==3; R+=Rs+2; Rs+=if(MaxRow()>=39,1,0); C:=0; Cs:=MaxCol()-1
- endcase
- case Ntw==4
- do case
- case j==2; C+=Cs+2
- case j==3; R+=Rs+2; C:=0; Rs+=if(MaxRow()>=39,1,0)
- case j==4; C+=Cs+2
- endcase
- case Ntw<=6
- do case
- case j<=3; C+=Cs+2; Cs+=if(j==3,2,0)
- case j==4; R+=Rs+2; C:=0; Cs-=2; Cs:=if(Ntw==5,Int((MaxCol()-1)/2)-1,Cs); Rs+=if(MaxRow()>=39,1,0)
- otherwise; C+=Cs+2; Cs+=if(j==6,2,0)
- endcase
- case Ntw==7
- do case
- case j<=3; C+=Cs+2; Cs+=if(j==3,2,0)
- case j==4 or j==6; R+=Rs+2; C:=0; Cs:=Int((MaxCol()-1)/2)-1; Rs+=if(j==6,1,0); Rs+=if(j==6 and MaxRow()>=49,1,0)
- otherwise; C+=Cs+2
- endcase
- otherwise //8,9
- do case
- case j<=3; C+=Cs+2; Cs+=if(j==3,2,0)
- case j==4; R+=Rs+2; C:=0; Cs-=2
- case j==7; R+=Rs+2; C:=0; Cs-=2; Rs++; Cs:=if(Ntw==8,Int((MaxCol()-1)/2)-1,Cs); Rs+=if(MaxRow()>=49,1,0)
- case j<=6; C+=Cs+2; Cs+=if(j==6,2,0)
- case j==9; C+=Cs+2; Cs+=2
- otherwise; C+=Cs+2
- endcase
- endcase
- endif
- if j<10
- SetCoords(TList[i],R,C,Rs,Cs)
- else
- TList[i]:Minimize(false)
- endif
- endif
- endfor
- endif
- Task:RePaint(true) //repaint!
- set lastkey K_ENTER
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // Task::Menu() --> newTask
- // local task menu.
- //
- static function Menu(Task)
- local Mnu,SelItems,Choice
- SelItems:=Array(10)
- AFill(SelItems,true)
- do case
- case Task:IsMax; SelItems[3]:=false
- case Task:IsMin; SelItems[2]:=false
- otherwise; SelItems[1]:=false
- endcase
- if Len(TList)==1
- SelItems[4]:=false //next window
- SelItems[5]:=false //previous w..
- SelItems[6]:=false //tile
- SelItems[7]:=false //cascade
- SelItems[10]:=false //switch to..
- endif
- object Mnu of Mnu; Mnu:Init(,Task:Row,Task:Col+2,0,ResTxt(129),SelItems)
- SaveDOut(ResTxt(140))
- Choice:=Mnu:Process()
- RestDOut()
- Mnu:Done()
- set lastkey K_ENTER
- do case
- case Choice==1; Task:Restore()
- case Choice==2; Task:Minimize()
- case Choice==3; Task:Maximize()
- case Choice==4; Task:=Switch(Task,true)
- case Choice==5; Task:=Switch(Task,false)
- case Choice==6; Tile(Task)
- case Choice==7; Cascade(Task)
- case Choice==8; Task:Drag()
- case Choice==9; Task:=Done(Task) //can change LastKey()
- case Choice==10; Task:=List(Task)
- endcase
- return(Task)
-
-
- //*****************************************************************************
- // Task:Done(lRePaint) --> nil
- // done task.
- //
- method function TaskDone(lRePaint)
- local i:=::ID
- returnif !Eval(::DoneBlock,self) with false
- returnif !::super(Window):Done(lRePaint) with false
- ::IsDead:=true
- LastTask:=if(Empty(TList), {}, ATail(GetWList()))
- if ::UpFlag; return(true); endif //done for keeping task
- ATrueDel(TList,AScan(TList,{|e|e:ID==i}))
- if i<=9; SetKey(K_ALT_1+i-1,nil); endif
- if Empty(TList)
- SetKey(K_ALT_0, nil) //task-list
- SetKey(K_F5, nil) //zoom-in
- SetKey(K_SH_F5, nil) //zoom-out
- SetKey(K_F6, nil) //switch-forward
- SetKey(K_SH_F6, nil) //switch-backward
- SetKey(K_F7, nil) //tile
- SetKey(K_SH_F7, nil) //cascade
- SetKey(K_F8, nil) //drag
- SetKey(K_SH_F10,nil) //local-window-menu
- ::RePaint(true)
- endif
- return(true)
-
- //------------------------------------------------------- eof (c)JHK ----------
-
-